package com.srv.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.srv.exceptions.CidadeInvalidaException;
import com.srv.exceptions.UsuarioInvalidoException;
import com.srv.exceptions.VeiculoInvalidoException;
import com.srv.pojo.Cidade;
import com.srv.pojo.GradeHoraria;
import com.srv.pojo.Reserva;
import com.srv.pojo.Usuario;
import com.srv.pojo.Veiculo;

public class DAOReserva extends DAOGenerico implements DAOGenericoInterface {

	public DAOReserva() throws ClassNotFoundException, SQLException {
		super();
	}

	@Override
	public void insert(Object object) throws Exception {
		Connection connection = this.getConnection();
		Reserva reserva = (Reserva) object;
		DAOVeiculo daoVeiculo = new DAOVeiculo();
		if (!daoVeiculo.existVeiculo(reserva.getVeiculo())) {
			daoVeiculo = null;
			throw new VeiculoInvalidoException(
					"O veiculo indicado não está cadastrado na base de dados!");
		}
		daoVeiculo = null;
		DAOUsuario daoUsuario = new DAOUsuario();
		if (!daoUsuario.existeUsuario(reserva.getUsuario())) {
			daoUsuario = null;
			throw new UsuarioInvalidoException(
					"O usuário indicado não está cadastrado na base de dados!");
		}
		DAOCidade daoCidade = new DAOCidade();
		if (!daoCidade.existeCidade(reserva.getCidadeDestino()) || !daoCidade.existeCidade(reserva.getCidadeOrigem())){
			daoCidade = null;
			throw new CidadeInvalidaException("A cidades informadas são inválidas!");
		}
		String sql = "insert into reserva (data_partida, poltrona_partida, data_retorno, poltrona_retorno, email, vecode, origem, destino, hora_partida, hora_retorno) " +
				"values (?,?,?,?,?,?,?,?,?,?)";
		PreparedStatement stmt = null;
		try {
			stmt = connection.prepareStatement(sql);
			stmt.setDate(1, new java.sql.Date(reserva.getDataPartida().getTime()));
			stmt.setString(2, reserva.getPoltronaPartida());
			stmt.setDate(3, new java.sql.Date(reserva.getDataRetorno().getTime()));
			stmt.setString(4, reserva.getPoltronaRetorno());
			stmt.setString(5, reserva.getUsuario().getEmail());
			stmt.setInt(6, reserva.getVeiculo().getVecode());
			stmt.setInt(7, reserva.getCidadeOrigem().getCicode());
			stmt.setInt(8, reserva.getCidadeDestino().getCicode());
			stmt.setInt(9, reserva.getHoraPartida().getGhcode());
			stmt.setInt(10, reserva.getHoraRetorno().getGhcode());
			stmt.execute();
			stmt.close();
		} catch (Exception e) {
			if ((stmt != null)&&(!stmt.isClosed())){
				stmt.close();
			}
			throw e;
		}
	}

	@Override
	public void update(Object object) throws Exception {
		Connection connection = this.getConnection();
		Statement st = connection.createStatement();
		String cmdUpdate = "UPDATE reserva SET " +
				" data_partida = '"+new SimpleDateFormat("yyyy-MM-dd").format( ((Reserva)object).getDataPartida() ) + "'" +
				", poltrona_partida = '"+( ((Reserva)object).getPoltronaPartida() ) + "'" +
				", data_retorno = '"+new SimpleDateFormat("yyyy-MM-dd").format( ((Reserva)object).getDataRetorno() ) + "'";
				
				if (((Reserva)object).getPoltronaRetorno() != null){
					cmdUpdate += ", poltrona_retorno = '"+( ((Reserva)object).getPoltronaRetorno() ) + "'";
				}
		
				cmdUpdate += ", email = '"+( ((Reserva)object).getUsuario().getEmail() ) + "'";
				cmdUpdate += ", vecode = "+( ((Reserva)object).getVeiculo().getVecode() );
				cmdUpdate += ", origem = "+( ((Reserva)object).getCidadeOrigem().getCicode() );
				cmdUpdate += ", destino = "+( ((Reserva)object).getCidadeDestino().getCicode() );
				cmdUpdate += ", hora_partida = '"+( ((Reserva)object).getHoraPartida().getGhcode() ) + "'";
				cmdUpdate += ", hora_retorno = '"+( ((Reserva)object).getHoraRetorno().getGhcode() )+ "'";
				cmdUpdate += " WHERE rescode = " + ((Reserva)object).getRescode() + ";";
		System.out.println("Reserva: "+cmdUpdate);
		st.executeUpdate(cmdUpdate);
		st.close();
	}

	@Override
	public void delete(Object object) throws SQLException {
		Connection connection = this.getConnection();
		Statement st = connection.createStatement();
		String cmdDelete = "DELETE FROM reserva WHERE rescode = "
				+ ((Reserva)object).getRescode() + ";";
		st.executeUpdate(cmdDelete);
		st.close();
	}
	
	public List<Reserva> getReservaList(Usuario user) throws SQLException, ClassNotFoundException {
		ResultSet rs = this.getResultSet("SELECT * FROM reserva WHERE email LIKE '"+user.getEmail()+"'");
		List<Reserva> reservaList = new ArrayList<Reserva>();
		DAOVeiculo daoVeiculo = new DAOVeiculo();
		DAOGradeHoraria daoGradeHoraria = new DAOGradeHoraria();
		//DAOUsuario daoUsuario = new DAOUsuario();
		//DAOCidade daoCidade = new DAOCidade();
		Reserva reserva = new Reserva();
		while (rs.next()) {
			reserva = new Reserva();
			reserva.setRescode(rs.getLong("rescode"));
			reserva.setDataPartida(rs.getDate("data_partida"));
			reserva.setDataRetorno(rs.getDate("data_retorno"));
			reserva.setHoraPartida(daoGradeHoraria.getGradeHorariaByGhcode(rs.getInt("hora_partida")));
			reserva.setHoraRetorno(daoGradeHoraria.getGradeHorariaByGhcode(rs.getInt("hora_retorno")));
			//reserva.setUsuario(daoUsuario.getUsuarioByLogin(rs.getString("email")));
			
			reserva.setVeiculo(daoVeiculo.getVeiculoByVecode(rs.getInt("vecode")));
			
			//reserva.setCidadeOrigem(daoCidade.getCidadeByCicode(rs.getInt("origem")));
			//reserva.setCidadeDestino(daoCidade.getCidadeByCicode(rs.getInt("destino")));
			reserva.setPoltronaPartida(rs.getString("poltrona_partida"));
			reserva.setPoltronaRetorno(rs.getString("poltrona_retorno"));
			reservaList.add(reserva);
		}
		rs.close();
		return reservaList;
	}
	
	public List<Reserva> getReservaList(Date data, GradeHoraria hora, Veiculo veiculo, Cidade origem, Cidade destino) throws Exception {
		DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		ResultSet rs = this.getResultSet("SELECT * FROM reserva WHERE ((" +
				"data_partida = '" + dateFormat.format(data) + "' AND " +
				"hora_partida = " + hora.getGhcode() + ") OR (" +
				"data_retorno = '" + dateFormat.format(data) + "' AND " +
				"hora_retorno = " + hora.getGhcode() + ")) AND " +
				"vecode = " + veiculo.getVecode() + " AND " +
				"origem = " + origem.getCicode() + " AND " +
				"destino = " + destino.getCicode() + ";");
		List<Reserva> reservaList = new ArrayList<Reserva>();
		DAOVeiculo daoVeiculo = new DAOVeiculo();
		DAOGradeHoraria daoGradeHoraria = new DAOGradeHoraria();
		DAOUsuario daoUsuario = new DAOUsuario();
		DAOCidade daoCidade = new DAOCidade();
		Reserva reserva = null;
		while (rs.next()) {
			reserva = new Reserva();
			reserva.setRescode(rs.getLong("rescode"));
			reserva.setDataPartida(rs.getDate("data_partida"));
			reserva.setDataRetorno(rs.getDate("data_retorno"));
			reserva.setHoraPartida(daoGradeHoraria.getGradeHorariaByGhcode(rs.getInt("hora_partida")));
			reserva.setHoraRetorno(daoGradeHoraria.getGradeHorariaByGhcode(rs.getInt("hora_retorno")));
			reserva.setUsuario(daoUsuario.getUsuarioByLogin(rs.getString("email")));
			reserva.setVeiculo(daoVeiculo.getVeiculoByVecode(rs.getInt("vecode")));
			reserva.setCidadeOrigem(daoCidade.getCidadeByCicode(rs.getInt("origem")));
			reserva.setCidadeDestino(daoCidade.getCidadeByCicode(rs.getInt("destino")));
			reserva.setPoltronaPartida(rs.getString("poltrona_partida"));
			reserva.setPoltronaRetorno(rs.getString("poltrona_retorno"));
			reservaList.add(reserva);
		}
		rs.close();
		return reservaList;
	}

	public Reserva getReservaByRescode(int rescode) throws SQLException, Exception{
		ResultSet rs = this.getResultSet("SELECT * FROM reserva WHERE rescode = " + rescode);
		DAOVeiculo daoVeiculo = new DAOVeiculo();
		DAOGradeHoraria daoGradeHoraria = new DAOGradeHoraria();
		DAOUsuario daoUsuario = new DAOUsuario();
		DAOCidade daoCidade = new DAOCidade();
		Reserva reserva = new Reserva();
		while (rs.next()){
			reserva.setRescode(rs.getInt("rescode"));
			reserva.setDataPartida(rs.getDate("data_partida"));
			reserva.setPoltronaPartida(rs.getString("poltrona_partida"));
			reserva.setDataRetorno(rs.getDate("data_retorno"));
			reserva.setPoltronaRetorno(rs.getString("poltrona_retorno"));
			
			reserva.setUsuario(daoUsuario.getUsuarioByLogin(rs.getString("email")));
			
			reserva.setVeiculo(daoVeiculo.getVeiculoByVecode(rs.getInt("vecode")));
			
			reserva.setCidadeOrigem(daoCidade.getCidadeByCicode(rs.getInt("origem")));
			reserva.setCidadeDestino(daoCidade.getCidadeByCicode(rs.getInt("destino")));
			reserva.setHoraPartida(daoGradeHoraria.getGradeHorariaByGhcode(rs.getInt("hora_partida")));
			reserva.setHoraRetorno(daoGradeHoraria.getGradeHorariaByGhcode(rs.getInt("hora_retorno")));
		}
		rs.close();
		return reserva;
	}

}
